package com.hrm.system.controller;

import com.hrm.common.controller.BaseController;
import com.hrm.common.entity.PageResult;
import com.hrm.common.entity.Result;
import com.hrm.common.entity.ResultCode;
import com.hrm.common.util.ExcelImportUtil;
import com.hrm.domain.system.User;
import com.hrm.domain.system.response.ProfileResult;
import com.hrm.domain.system.response.UserResult;
import com.hrm.system.client.DepartmentFeignClient;
import com.hrm.system.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

@CrossOrigin
@RestController
@RequestMapping(value = "/sys") //sys/user
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private DepartmentFeignClient departmentFeignClient;

    /**
     * 保存用户
     */
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public Result addUser(@RequestBody User User) {
        User.setCompanyId(companyId);
        userService.addUser(User);
        //响应结果
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 更新用户
     */
    @RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
    public Result updateUser(@PathVariable(value = "id") String id, @RequestBody User User) {
        User.setId(id);
        userService.updateUser(User);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * id查找用户
     */
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public Result findUserById(@PathVariable(value = "id") String id) {
        UserResult userResult = new UserResult(userService.findUserById(id));
        return new Result(ResultCode.SUCCESS, userResult);
    }

    /**
     * 查找用户列表
     * 返回数据分页
     */
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public Result findUsers(Integer page, Integer size, @RequestParam Map<String, Object> map) {
        Page<User> userPage = userService.findUsers(map, page, size);
        return new Result(ResultCode.SUCCESS, new PageResult<>(userPage.getTotalElements(), userPage.getContent()));
    }

    /**
     * id删除用户
     */
    @RequiresPermissions(value = "API-USER-DELETE")
    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    public Result deleteCompany(@PathVariable(value = "id") String id) {
        userService.deleteUser(id);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 分配角色
     * put请求userid和roleid的map集合
     */
    @RequestMapping(value = "/user/asignRoles", method = RequestMethod.PUT)
    public Result asignRoles(@RequestBody Map<String, Object> map) {
        //获取userid 和 roleid集合
        String userId = (String) map.get("id");
        List<String> roleIds = (List<String>) map.get("roleIds");
        //调用asignRoles方法
        userService.asignRoles(userId, roleIds);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 登录api：
     * 验证登录信息，签发token
     * token中存入userid、username、companyid、companyname、apis
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Result login(@RequestBody Map<String, Object> loginMap) {
        String mobile = (String) loginMap.get("mobile");
        User user = userService.findByMobile(mobile);
        String password = (String) loginMap.get("password");
        //1、构造登录令牌(加密密码)
        Md5Hash md5Hash = new Md5Hash(password, mobile, 3);
        UsernamePasswordToken upToken = new UsernamePasswordToken(mobile, md5Hash.toString());
        //2、获取subject
        Subject subject = SecurityUtils.getSubject();
        try {
            //3、login、并获取sessionId
            subject.login(upToken);
            String sessionId = (String) subject.getSession().getId();
            //4、构造返回结果
            return new Result(ResultCode.SUCCESS, sessionId);
        } catch (Exception e) {
            return new Result(ResultCode.MOBILE_OR_PASSWORD_ERROR);
        }
    }

    /**
     * 获取用户信息:账号、企业、角色
     */
    @RequestMapping(value = "/profile", method = RequestMethod.POST)
    public Result profile(HttpServletRequest request) {
        //获取session中的安全数据
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection principals = subject.getPrincipals();
        ProfileResult profileResult = (ProfileResult) principals.getPrimaryPrincipal();
        return new Result(ResultCode.SUCCESS, profileResult);
    }

    /**
     * 从企业微服务中根据id查询
     */
    @RequestMapping(value = "/test/{id}", method = RequestMethod.GET)
    public Result test(@PathVariable String id) {
        Result result = departmentFeignClient.findDepartmentById(id);
        return result;
    }

    /**
     * 导入excel，批量新增用户
     * 重写：抽取工具类进行导入
     */
    @RequestMapping(value = "/user/import", method = RequestMethod.POST)
    public Result importExcel(@RequestParam(name = "file") MultipartFile file) throws Exception {
        //导入的excel以MultipartFile文件的形式
        //解析excel内容
        //1.根据Excel文件创建工作簿
        InputStream inputStream = file.getInputStream();
        List<User> users = new ExcelImportUtil<User>(User.class).readExcel(inputStream, 1, 1);
        userService.addUsers(users, companyId, companyName);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 上传用户图片
     *      返回image的dataurl
     */
    @RequestMapping(value = "/user/upload/{id}", method = RequestMethod.PUT)
    public Result upload(@PathVariable String id, @RequestParam(name = "file") MultipartFile file) throws IOException {
        String image = userService.uploadImage(id, file);
        return new Result(ResultCode.SUCCESS, image);
    }

}
